package com.google.jessewilson.codesearch.ui;

import ca.odell.glazedlists.TreeList;
import com.google.jessewilson.codesearch.api.QueryResponse;
import com.google.jessewilson.codesearch.ui.tree.Element;

import javax.swing.*;

/**
 * Actions for controlling the display of the results tree.
 *
 * @author jessewilson
 */
public class ResultsTreeActions {

  private final QueryResponse results;
  private final TreeList<Element> elements;
  private final JTable table;
  private final ResultActionsProvider resultActionsProvider;

  private final ListSelectionModel selectionModel;

  public ResultsTreeActions(TreeList<Element> elements,
      JTable table, ResultActionsProvider resultActionsProvider,
      QueryResponse results) {
    this.elements = elements;
    this.table = table;
    this.resultActionsProvider = resultActionsProvider;
    this.results = results;

    selectionModel = table.getSelectionModel();
  }

  public void expandAll() {
    elements.getReadWriteLock().writeLock().lock();
    try {
      for(int i = 0; i < elements.size(); i++) {
        elements.setExpanded(i, true);
      }
    } finally {
      elements.getReadWriteLock().writeLock().unlock();
    }
  }

  public void collapseAll() {
    // to deeply collapse all, we must expand all first
    expandAll();

    // collapse from bottom to top, so children are collapsed before their parents
    for(int i = elements.size() - 1; i >= 0; i--) {
      i = Math.min(i, elements.size() - 1);
      elements.setExpanded(i, false);
    }
  }

  public void next() {
    selectRow(selectionModel.getMinSelectionIndex() + 1);
  }

  public void previous() {
    selectRow(selectionModel.getMinSelectionIndex() - 1);
  }

  /**
   * Select the specified row, wrapping around as necessary.
   */
  private void selectRow(int newSelectedIndex) {
    int rowCount = table.getRowCount();
    newSelectedIndex = (newSelectedIndex + rowCount) % rowCount;

    // select the new element
    selectionModel.setSelectionInterval(newSelectedIndex, newSelectedIndex);

    // update the view
    table.scrollRectToVisible(table.getCellRect(newSelectedIndex, 0, true));

    // kick off the action
    Element selected = elements.get(newSelectedIndex);
    resultActionsProvider.doDefaultAction(selected.getFile(), selected.getLine(), results);
  }

}
